
package SocKet;


import ManagerInfoFile.FileNodeMap;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;

public class Server {
    private DatagramSocket dataGramSocket;
    private int port1;
    private int port2;
    private String address1;
    private String address2;
    private InetAddress IPAddress1;
    private InetAddress IPAddress2;
    private FileNodeMap dsNode;
    private FileInputStream fis;
    private int maxLengthData = 64512;
    public Server()
    {
        this.dataGramSocket = null;
        this.port1 = 0;
        this.port2 = 0;
        this.address1 = null;
        this.address2 = null;
        dsNode = new FileNodeMap();
    }
    public InetAddress GetIpAdress()
    {
        return this.IPAddress1;
    }
    public int GetPort()
    {
        return this.port1;
    }
    public void ReadDataNode()
    {
        dsNode.ReadNodeMap(dsNode.GetFileName());
        this.address1 = dsNode.GetNodeInfo(0).GetIpAddress();
        this.port1 = dsNode.GetNodeInfo(0).GetPort();
        try {
            this.IPAddress1 = InetAddress.getByName(this.address1);
        } catch(UnknownHostException ex) {
            System.out.println("Lỗi- Host Name Không Hợp Lệ " + ex.getMessage());
        }
        
    }
    public String SplitString(String str)
    {
        String [] strlist = str.split("-");
        if(strlist.length>0)
        {
            return strlist[0];
        }
        return null;
    }
    public void ReceiverBroadCast()
    {
        try {
            dataGramSocket = new DatagramSocket(this.port1);
            byte[] dataReceive = new byte[1024];
            int length =0;
            int i = 0;
            File file;
            String reply ="";
            
            byte[] dataSend;
            String message;
            //tao datagreampacket de nhan data
            DatagramPacket receivePacket;
            DatagramPacket sendPacket;
            
            receivePacket= new DatagramPacket(dataReceive,0, 4);
            // ham nhan datagrampacket 
            dataGramSocket.receive(receivePacket);
            message = new String(receivePacket.getData());
            length = Integer.parseInt(SplitString(message));
           
            System.out.println(">>>>>"+length);
            
            IPAddress2 = receivePacket.getAddress();
            port2 = receivePacket.getPort();
            
            while(true)
            {
               if(i>=length)
                   break;
                receivePacket= new DatagramPacket(dataReceive, dataReceive.length);
               // ham nhan datagrampacket 
               dataGramSocket.receive(receivePacket);
               message = new String(receivePacket.getData());
            
               System.out.println("receive client "+message);
               
               file = new File("./Data/Share/"+message);
               boolean fileExists = file.exists();

               if(fileExists)
               { 
                   reply = "YES-";
                   dataSend  = reply.getBytes();
                   
                   sendPacket = new DatagramPacket(dataSend, dataSend.length, IPAddress2, port2);
                   dataGramSocket.send(sendPacket);
                   System.out.println(reply);
               }
               else
               {
                   reply = "NO-";
                   dataSend  = reply.getBytes();
                   sendPacket = new DatagramPacket(dataSend, dataSend.length, IPAddress2, port2);
                   dataGramSocket.send(sendPacket);
                   System.out.println(reply);
               }
               i++;
            }
            dataGramSocket.close();
            while(true)
            {
                 NhanYeuCauSendFile();
            }
        } catch (UnknownHostException e) {
            System.out.println("Lỗi - Ipadress Sai "+ e.getMessage());
        } catch (SocketException e) {
            System.out.println("Lỗi - Phương Thức Kết Nối Socket "+e.getMessage());
        } catch (IOException e) {
            System.out.println("Lỗi - File "+e.getMessage());
        }
        
    }
    //nhan yeu cau send file tu client
    public void NhanYeuCauSendFile()
    {  
        try {
            dataGramSocket = new DatagramSocket(this.port1);
            byte[] dataReceive = new byte[1024];
            DatagramPacket  receivePacket;
            DatagramPacket sendPacket ;
            receivePacket= new DatagramPacket(dataReceive, dataReceive.length);
            // ham nhan datagrampacket 
            dataGramSocket.receive(receivePacket);
            IPAddress2 = receivePacket.getAddress();
            port2 = receivePacket.getPort();
            System.out.println(">>>>>>>>>>>>>Nhận dc yêu cầu");
            String  filename = new String(receivePacket.getData());
            File file = new File("./Data/Share/"+filename);
            byte[] dataFile = new byte[(int) file.length()];
	        
            fis = new FileInputStream(file);
	   
            fis.read(dataFile);
            int n = 0;
            byte[] Data; 
	        
	    List<byte[]> listData = new ArrayList<byte[]>();
	      
	    int phanle=0;
	    //if(dataFile.length < maxLengthData)
	        	//return;
	    n = dataFile.length/maxLengthData;
	    phanle = dataFile.length % maxLengthData;
	    
            for(int i = 0;i < n ; i++)
            {
                Data = new byte[maxLengthData];
                for(int j = 0; j < maxLengthData; j++)
                {
                    Data[j] = dataFile[i*maxLengthData + j];
                }
                listData.add(Data);
            }
            if(phanle>0)
            {
                Data = new byte[phanle];
                for(int i=0; i < phanle;i++)
                {
                    Data[i] = dataFile[n*maxLengthData+i];  
                }
                listData.add(Data);
            }
            // send thong tin qua client can nhan du lieu bao nhieu lan
            byte[] dataSend ;
            String str = ""+listData.size()+"-";
            dataSend = str.getBytes();
            sendPacket = new DatagramPacket(dataSend, dataSend.length, IPAddress2, port2);
            dataGramSocket.send(sendPacket);
            
            
            // send
            int dem =0;
            System.out.println("kich thuoc"+listData.size());
            while(true)
            {
                if(dem >= listData.size())
                {
                    System.out.println("Gởi Hoàn Thành File chunk cho Client");
                    break;
                }
                //nhan
                receivePacket= new DatagramPacket(dataReceive,0, dataReceive.length);
                dataGramSocket.receive(receivePacket);
                String strdem = new String(receivePacket.getData());
               
                dem = Integer.parseInt(SplitString(strdem));
                System.out.println("Server nhận được yêu cầu send gói thư "+dem);
                
                //send data theo goi thu i ma client cần
                String data = new String(listData.get(dem));
                data = data +"-";
                dataSend = data.getBytes();
                sendPacket = new DatagramPacket(dataSend, dataSend.length, IPAddress2, port2);
                dataGramSocket.send(sendPacket);
                System.out.println("Server gởi data goi thu "+dem+" >>>>>>>>>>>>>>>>>");
                
                dem++;
               
            }
            dataGramSocket.close();
        } catch(IOException io){
            System.out.println("Lỗi- Socket "+io.getMessage());
        }
    }
}
